package com.yxp423.ssmempl.service.impl;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yxp423.ssmempl.bean.Process;
import com.yxp423.ssmempl.bean.Project;
import com.yxp423.ssmempl.bean.User;
import com.yxp423.ssmempl.bean.UserProject;
import com.yxp423.ssmempl.dto.ProcessDto;
import com.yxp423.ssmempl.mapper.ProcessMapper;
import com.yxp423.ssmempl.mapper.ProjectMapper;
import com.yxp423.ssmempl.mapper.UserMapper;
import com.yxp423.ssmempl.mapper.UserProjectMapper;
import com.yxp423.ssmempl.service.IProjectService;
import com.yxp423.ssmempl.utils.ProcessEnum;
import com.yxp423.ssmempl.utils.base.AjaxResult;
import com.yxp423.ssmempl.utils.consts.ApplyConst;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

/**
 * @Description: java类作用描述
 * @Author: yxp
 * @CreateDate: 2019-05-11 16:23
 * @Version: 1.0
 */
@Service
public class ProjectServiceImpl implements IProjectService {

	@Autowired
	private ProjectMapper projectMapper;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private ProcessMapper processMapper;
	@Autowired
	private UserProjectMapper userProjectMapper;


	Cache<String, Project> projectCache = CacheUtil.newLRUCache(10, DateUnit.MINUTE.getMillis() * 5);

	Cache<String, IPage<Project>> projectPagesCache = CacheUtil.newLRUCache(10, DateUnit.MINUTE.getMillis() * 5);
	Cache<String, User> projectUsersCache = CacheUtil.newLRUCache(10, DateUnit.MINUTE.getMillis() * 5);

	@Override
	public AjaxResult saveProjectApply(Project project) {

		AjaxResult result = new AjaxResult();

		User user = (User) SecurityUtils.getSubject().getPrincipal();
		if (ObjectUtil.isNull(user)) {

			result.setSuccess(false);
			result.setMsg("请登录");

		}
		try {
			project.setCreateTime(DateUtil.date());
			project.setCreatorId(user.getUserId().toString());
			project.setIsdelete(ApplyConst.NOT_DELETE);
			project.setVersion(1);
			project.setProjectStatus(ApplyConst.STATUS_CHECKING);

			int flag = projectMapper.insert(project);

			if (flag > 0) {

				Project projectById = projectMapper.selectByProjectId(project.getProjectId());

				if (ObjectUtil.isNotNull(projectById)) {

					result.setSuccess(true);
					result.setMsg("添加成功");

					projectCache.clear();
					projectCache.put(projectById.getProjectId(), projectById);

				} else {

					result.setSuccess(false);
					result.setMsg("添加失败");

				}

			} else {
				result.setSuccess(false);
				result.setMsg("添加失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setMsg("发生错误" + e.toString());
		}

		return result;
	}

	@Override
	public AjaxResult getCheckingProject(IPage<Project> page) {

		AjaxResult result = new AjaxResult();

		User user = (User) SecurityUtils.getSubject().getPrincipal();
		if (ObjectUtil.isNull(user)) {
			result.setSuccess(false);
			result.setMsg("请登录");
			return result;
		}
		try {

			if (ObjectUtil.isEmpty(projectPagesCache) || ObjectUtil.isEmpty(projectPagesCache.get("projectPage" + page.getCurrent()))) {

				QueryWrapper<Project> wrapper = new QueryWrapper<>();

				IPage<Project> projectPage = projectMapper.selectPage(page, wrapper
						.eq("project_status", ApplyConst.STATUS_CHECKING)
						.eq("reviewer_id", user.getUserId())
						.eq("isdelete", ApplyConst.NOT_DELETE)
						.orderByDesc("create_time"));

				if (ObjectUtil.isNotNull(projectPage)) {

					for (Project record : projectPage.getRecords()) {

						User userById = userMapper.getUserById(Integer.parseInt(record.getCreatorId()));
						if (ObjectUtil.isNotNull(userById)) {

							record.setCreateName(userById.getName());
							projectUsersCache.put("user" + userById.getUserId(), userById);

						} else {
							result.setSuccess(false);
							result.setMsg("获取申请用户失败");
							StaticLog.error("获取申请用户失败");
							return result;
						}

					}

					result.setSuccess(true);
					result.setMsg("获取数据成功");
					result.setData(projectPage);

					projectPagesCache.put("projectPage" + page.getCurrent(), projectPage);

				} else {

					result.setSuccess(false);
					result.setMsg("获取分页数据失败");
					return result;
				}
			} else {

				result.setSuccess(true);
				result.setData(projectPagesCache.get("projectPage" + page.getCurrent()));

			}

		} catch (Exception e) {

			result.setSuccess(false);
			result.setMsg(e.toString());
			e.printStackTrace();

		}
		return result;
	}

	@Override
	public AjaxResult saveProjectReview(Project project) {
		AjaxResult result = new AjaxResult();

		User user = (User) SecurityUtils.getSubject().getPrincipal();
		if (ObjectUtil.isNull(user)) {


			result.setSuccess(false);
			result.setMsg("请登录");
			return result;

		}

		try {

			Project selectById = projectMapper.selectById(project.getProjectId());

			if (ObjectUtil.isNull(selectById)) {

				result.setSuccess(false);
				result.setMsg("找不到该项目");
				return result;
			}

			project.setVersion(selectById.getVersion());
			project.setReviewTime(DateUtil.date());

			int flag = projectMapper.updateById(project);

			if (flag > 0) {

				result.setSuccess(true);
				result.setMsg("审核成功，受影响行数" + flag);
				projectPagesCache.clear();

			} else {

				result.setSuccess(false);
				result.setMsg("审核失败");
			}


		} catch (Exception e) {
			result.setSuccess(false);
			result.setMsg(e.toString());
			e.printStackTrace();
		}

		return result;
	}

	@Override
	public AjaxResult updateProject(Page<Project> page) {

		AjaxResult result = new AjaxResult();

		try {
			User user = (User) SecurityUtils.getSubject().getPrincipal();
			if (ObjectUtil.isNull(user)) {

				result.setSuccess(false);
				result.setMsg("请登录");
				return result;

			}

			QueryWrapper<Project> wrapper = new QueryWrapper<>();

			IPage<Project> projects = projectMapper.selectPage(page, wrapper
					.eq("isdelete", ApplyConst.NOT_DELETE)
					.eq("creator_id", user.getUserId())
					.eq("project_status", ApplyConst.STATUS_CHECKED)
			);
			if (ObjectUtil.isNull(projects)) {

				result.setSuccess(false);
				result.setMsg("未找到项目");
				return result;
			}

			for (Project record : projects.getRecords()) {

				record.setCreateName(user.getName());

			}

			result.setSuccess(true);
			result.setData(projects);


		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setMsg(e.toString());
		}

		return result;
	}

	@Override
	@Transactional(rollbackFor = RuntimeException.class)
	public AjaxResult updateSubmit(ProcessDto processDto) {


		AjaxResult result = new AjaxResult();

		boolean isSuccess = false;

		User user = (User) SecurityUtils.getSubject().getPrincipal();
		if (ObjectUtil.isNull(user)) {

			result.setSuccess(false);
			result.setMsg("请登录");
			return result;

		}

		try {

			JSONArray usersArr = JSONUtil.parseArray(processDto.getUsers());

			if (ObjectUtil.isNotEmpty(usersArr)) {

				List<UserProject> userProjectList = userProjectMapper.selectList(new QueryWrapper<UserProject>().eq("project_id", processDto.getProjectId()));

				String[] ids = new String[0];

				for (UserProject userProject : userProjectList) {
					ids = ArrayUtil.append(ids, userProject.getUserId());//将查出来的该项目的所有员工id添加到ids数组中
				}

				for (Object userId : usersArr) {

					boolean exist = ArrayUtil.contains(ids, userId.toString());//判断当前循环到的id是否已在数据库中

					if (!exist) {    //不存在
						//在用户项目表中赋值（把多个用户添加到一个项目中）
						UserProject userProject = new UserProject();
						userProject.setProjectId(processDto.getProjectId());
						userProject.setUserId(userId.toString());
						userProjectMapper.insert(userProject);

					}

				}
			}

			Field[] fields = processDto.getClass().getDeclaredFields();
//			QueryWrapper<Process> wrapper = new QueryWrapper<Process>();
			for (Field field : fields) {

				field.setAccessible(true);
				String fieldName = field.getName();

				ProcessEnum[] values = ProcessEnum.values();
				for (ProcessEnum value : values) {
					if (fieldName.equals(value.geteName())) {

						Process process = new Process();
						process.setUpdateItem(value.getcName());

						Object itemValue = field.get(processDto);
						if (ObjectUtil.isNotNull(itemValue)) {

							process.setNewValue(itemValue.toString());
						}
						process.setUpdateTime(DateUtil.date());
						process.setItemField(fieldName);
						process.setCreatorId(user.getUserId().toString());
						process.setProjectId(processDto.getProjectId());
						process.setUpdateDesc(processDto.getUpdateDesc());

						int flag = processMapper.insert(process);
						if (flag > 0) {

							isSuccess = true;

						} else if (flag < 0) {
							isSuccess = false;
							break;
						}


						break;
					}
				}

//				if (!isSuccess) {
//					result.setSuccess(false);
//					result.setMsg("提交失败,失败项为" + fieldName);
//					return result;
//				}

			}

			result.setSuccess(true);
			result.setMsg("提交成功");


		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setMsg("异常信息：" + e.toString());
		}


		return result;
	}

	@Override
	public AjaxResult getMyProject(UserProject userProject) {

		AjaxResult result = new AjaxResult();
		QueryWrapper<Project> wrapper = new QueryWrapper<>();

		try {
			List<UserProject> list = userProjectMapper.selectList(new QueryWrapper<UserProject>().eq("user_id", userProject.getUserId()));

			if (ObjectUtil.isEmpty(list)){
				result.setSuccess(false);
				result.setMsg("你没有加入项目或用户id错误");
				result.setStatusCode(AjaxResult.REJECT);
				return result;
			}

			List<Project> projectList = new ArrayList<>();
			for (UserProject project : list) {

				Project projectById = projectMapper.selectById(project.getProjectId());

				if (ObjectUtil.isNull(projectById)){
					result.setSuccess(false);
					result.setMsg("获取项目失败");
					return result;
				}
				projectList.add(projectById);
			}

			if (ObjectUtil.isNotEmpty(projectList)){
				result.setSuccess(true);
				result.setStatusCode(AjaxResult.SUCCESS);
				result.setData(projectList);
				result.setMsg("获取成功");
			}else {
				result.setSuccess(false);
				result.setMsg("获取失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			result.setSuccess(false);
			result.setMsg("错误，错误信息为"+e.toString());
		}

		return result;
	}


}
